﻿/************
* 摘要:工位机扫码装托界面 MVVM
* 软件名称: 雪克码 工位机 系统
* 文件名: PackPalletViewModel.cs
* 版本: 1.0
*/
using AutoMapper;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using CommunityToolkit.Mvvm.Messaging.Messages;
using Microsoft.Extensions.Logging;
using ShanNiang.Hosting;
using ShanNiang.Mvvm.SaveModels;
using ShanNiang.Mvvm.UiServices;
using ShanNiang.Service;
using ShanNiang.Service.Attributes;
using ShanNiang.Service.Constants;
using ShanNiang.Service.Enumerate;
using ShanNiang.Service.Interfaces;
using ShanNiang.Service.PackingModels.Requests;
using ShanNiang.Service.Scaner;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Threading;

namespace ShanNiang.Mvvm.ViewModels
{
    //[ViewModelFile("pack_pallet.json", typeof(PackPalletModel))]
    public partial class PackPalletViewModel : ScannableViewModel, IRecipient<ValueChangedMessage<List<string?>>>
    {
        #region 服务注入
        private readonly IXkmService _xkmService;
        private readonly UserContext _userContext;
        private readonly ISoundService _soundService;
        private readonly Dispatcher _dispatcher;
        #endregion
        public PackPalletViewModel(
            IXkmService xkmService,
            UserContext userContext,
            IUiService uiService,
            ISoundService soundService,
            Dispatcher dispatcher,
            PackingConfig packingConfig, IScanerService scanerService, IMapper mapper, ILogger<PackPalletViewModel> logger) : base(packingConfig, scanerService, uiService, mapper, logger)
        {
            _xkmService = xkmService;
            _userContext = userContext;
            _soundService = soundService;
            _dispatcher = dispatcher;
            BoxCodes = new ObservableCollection<BoxViewModel>();
            LoadData();
        }
        #region 字段和可观察属性
        /// <summary>
        /// 箱码集合
        /// </summary>
        [ObservableProperty]
        private ObservableCollection<BoxViewModel> _boxCodes;
        /// <summary>
        /// 修改状态
        /// </summary>
        [ObservableProperty]
        private bool _modification;
        /// <summary>
        /// 托码
        /// </summary>
        [ObservableProperty]
        private string? _palletCode;
        /// <summary>
        /// 扫码删除
        /// </summary>
        [ObservableProperty]
        private bool _scanToDelete;
        /// <summary>
        /// 当前商品
        /// </summary>
        [ObservableProperty]
        private ItemViewModel? _currentItem;

        /// <summary>
        /// 当前企业
        /// </summary>
        private Guid? CurrentEnterpriseId
        {
            get
            {
                if (_userContext.UserResponse != null)
                {
                    return _userContext.UserResponse.EnterpriseId;
                }
                return null;
            }
        }
        public bool PalletValid => !string.IsNullOrWhiteSpace(PalletCode);
        #endregion

        #region 可绑定 Command
        /// <summary>
        /// 添加箱码
        /// </summary>
        /// <returns></returns>
        [RelayCommand]
        private async Task AddBoxAsync()
        {
            await Task.CompletedTask;
        }
        /// <summary>
        /// 拆托
        /// </summary>
        /// <returns></returns>
        [RelayCommand]
        private async Task BreakPalletCodeAsync()
        {
            if (Modification && PalletCode != null)
            {
                var request = new UnpackPalletRequest(PalletCode, CurrentEnterpriseId);
                try
                {
                    var result = await _xkmService.UnpackPalletAsync(request);
                    UiService.GrowlSuccess("拆托成功", CodeType.PalletCode);
                    ClearPalletCode();
                }
                catch (ApiException ex)
                {
                    UiService.GrowlWarning(ex.Message, CodeType.BoxCode, ex);
                }
                catch (Exception ex)
                {
                    UiService.GrowlError(ex.Message, CodeType.BoxCode, ex);
                }
            }
        }
        /// <summary>
        /// 清除托码
        /// </summary>
        [RelayCommand]
        private void ClearPalletCode()
        {
            PalletCode = null;
            Modification = false;
            BoxCodes.Clear();
            CurrentItem = null;
        }
        /// <summary>
        /// 删除一箱码
        /// </summary>
        /// <param name="box"></param>
        [RelayCommand]
        private void DeleteBox(BoxViewModel box)
        {
            if (box != null)
            {
                //var boxViewModel = (BoxViewModel)box;
                BoxCodes.Remove(box);
                if (BoxCodes.Count == 0)
                {
                    CurrentItem = null;
                }
            }
        }
        /// <summary>
        /// 封箱
        /// </summary>
        [RelayCommand]
        private async Task PackingPalletAsync()
        {
            await SavePalletAsync(Task.Run(() =>
            {
                _dispatcher.Invoke(() =>
                {
                    ClearPalletCode();
                    UiService.GrowlSuccess("封托成功", CodeType.PalletCode);
                });
            }));
        }
        /// <summary>
        /// 刷新项目
        /// </summary>
        /// <returns></returns>
        [RelayCommand]
        public async Task RefreshBoxCodesAsync()
        {
            if (CurrentItem != null)
            {
                var codes = BoxCodes.Select(p => p.BoxCode).ToList();
                var request = new RefreshBoxCodesRequest(codes, CurrentEnterpriseId);
                var response = await _xkmService.RefreshBoxCodesAsync(request);
                if (response != null)
                {
                    _dispatcher.Invoke(() =>
                    {
                        foreach (var boxCode in BoxCodes)
                        {
                            if (boxCode != null && boxCode.BoxCode != null)
                            {
                                if (response.TryGetValue(boxCode.BoxCode, out var box))
                                {
                                    boxCode.BottleCount = box.BottleCount;
                                    boxCode.IsFull = CurrentItem.BoxSize == box.BottleCount;
                                }
                            }
                        }
                    });
                }
            }
            else
            {
                //UiService.GrowlSuccess("请先确定装箱商品", CodeType.PalletCode);
            }
        }
        /// <summary>
        /// 保存托码
        /// </summary>
        /// <returns></returns>
        [RelayCommand()]
        private async Task SavePalletAsync()
        {
            await SavePalletAsync(Task.Run(() =>
            {
                Modification = true;
                UiService.GrowlSuccess("保存成功", CodeType.PalletCode);

            }));
        }
        #endregion

        #region 重写和事件处理
        protected override void OnPropertyChanged(PropertyChangedEventArgs e)
        {
            if (e.PropertyName == nameof(PalletCode) || e.PropertyName == nameof(CurrentItem))
            {
                OnPropertyChanged(nameof(PalletValid));
            }

            base.OnPropertyChanged(e);
        }
        protected override async Task CodeScanedAsync(object? sender, CodeEventArgs e)
        {
            if (e.CodeType == CodeType.PalletCode)
            {
                await ScanPalletcodeAsync(e.Code);
            }
            else if (e.CodeType == CodeType.BoxCode)
            {
                await ScanBoxcodeAsync(e.Code);
            }
            else
            {
                _soundService.PlayWanning(CodeType.Unknown);
            }
        }
        protected override Task LoadedAsync()
        {
            IsActive = true;
            return base.LoadedAsync();
        }
        #endregion

        #region 其他方法

        private async Task SavePalletAsync(Task? successCallback)
        {
            if (PalletCode == null)
            {
                UiService.GrowlInfo("请扫托码", CodeType.Unknown);
                return;
            }
            if (CurrentItem == null)
            {
                UiService.GrowlInfo("请扫箱码", CodeType.Unknown);
            }
            var request = new SavePalletRequest(PalletCode, CurrentEnterpriseId);
            foreach (var box in BoxCodes)
            {
                if (box != null && box.BoxCode != null)
                {
                    request.BoxCodes.Add(box.BoxCode);
                }
            }
            try
            {
                var result = await _xkmService.SavePalletAsync(request);
                if (result != null)
                {
                    if (successCallback != null)
                    {
                        await successCallback;
                    }
                    //ClearPalletCode();
                    //UiService.GrowlSuccess("装托成功", CodeType.PalletCode);
                }
            }
            catch (ApiException ex)
            {
                UiService.GrowlWarning(ex.Message, CodeType.BoxCode, ex);
            }
            catch (Exception ex)
            {
                UiService.GrowlError(ex.Message, CodeType.BoxCode, ex);
            }
        }
        private async Task ScanBoxcodeAsync(string code)
        {
            var boxCodeViewModel = BoxCodes.Where(p => p.BoxCode == code).FirstOrDefault();
            //SystemSounds.Beep.Play();
            if (ScanToDelete)
            {
                //var boxCodeViewModel = BoxCodes.Where(p=>p.BoxCode == code).FirstOrDefault();
                if (boxCodeViewModel != null)
                {
                    DeleteBox(boxCodeViewModel);
                    _soundService.PlayInfo(CodeType.Barcode);
                    return;
                }
                else
                {
                    UiService.GrowlWarning($"箱码{code}无效，无法删除", CodeType.BoxCode);
                    return;
                }
            }
            else
            {
                if (boxCodeViewModel != null)
                {
                    UiService.GrowlWarning($"箱码{code}已装入托盘,请换下一箱", CodeType.BoxCode);
                    return;
                }
                else
                {
                    var codes = BoxCodes.Select(p => p.BoxCode);
                    var request = new GetBoxCodeRequest(code, CurrentEnterpriseId);
                    //var request = new RefreshBoxCodesRequest(codes, CurrentEnterpriseId);
                    try
                    {
                        var boxCodeRsp = await _xkmService.GetBoxCodeAsync(request);
                        if (boxCodeRsp != null)
                        {
                            if (boxCodeRsp.Item == null)
                            {
                                UiService.GrowlWarning("空箱码无法装托", CodeType.BoxCode);
                                return;
                            }
                            if (CurrentItem == null)
                            {
                                CurrentItem = Mapper.Map<ItemViewModel>(boxCodeRsp.Item);
                            }
                            if (CurrentItem.Id != boxCodeRsp.ItemId)
                            {
                                UiService.GrowlWarning($"不同商品{boxCodeRsp.Item.Name}不能装入统一托盘", CodeType.BoxCode);
                                return;
                            }
                            boxCodeViewModel = Mapper.Map<BoxViewModel>(boxCodeRsp);
                            boxCodeViewModel.BottleCount = boxCodeRsp.BottleCodes.Count;
                            boxCodeViewModel.IsFull = CurrentItem.BoxSize == boxCodeRsp.BottleCodes.Count;

                            // darjet 2025-10-21 由于网络不稳，响应回来后再
                            if (!BoxCodes.Any(p => p.BoxCode == code))
                            {
                                BoxCodes.Insert(0, boxCodeViewModel);
                                _soundService.PlayInfo(CodeType.BoxCode);
                                //给本窗口发消息，获取箱码可以添加到列表
                                var boxCodes= BoxCodes.Select(p=>p.BoxCode).ToList();
                                if (boxCodes != null)
                                {
                                    WeakReferenceMessenger.Default.Send(new ValueChangedMessage<List<string?>>(boxCodes));
                                }
                            }
                            return;
                        }
                    }
                    catch (ApiException ex)
                    {
                        UiService.GrowlWarning(ex.Message, CodeType.BoxCode, ex);
                    }
                    catch (Exception ex)
                    {
                        UiService.GrowlError(ex.Message, CodeType.BoxCode, ex);
                    }
                }
            }
        }
        private async Task ScanPalletcodeAsync(string code)
        {
            if (ScanToDelete)
            {
                if (code == PalletCode)
                {
                    ClearPalletCode();
                    _soundService.PlayInfo(CodeType.PalletCode);
                    return;
                }
                else
                {
                    UiService.GrowlWarning($"箱码{code}无效", CodeType.PalletCode);
                    return;
                }
            }
            else
            {
                if (!PalletValid)
                {
                    //无商品，可以扫已装托码，进行修改
                    if (CurrentItem == null)
                    {
                        var detailRequest = new GetPalletDetailRequest(code, CurrentEnterpriseId);
                        try
                        {
                            var palletDetail = await _xkmService.GetPalletDetailAsync(detailRequest);
                            if (palletDetail != null)
                            {
                                PalletCode = palletDetail.Code;
                                //已装箱进入修改模式
                                if (palletDetail.Item != null)
                                {
                                    Modification = true;
                                    CurrentItem = Mapper.Map<ItemViewModel>(palletDetail.Item);
                                    foreach (var boxCode in palletDetail.Boxes)
                                    {
                                        var boxViewModel = Mapper.Map<BoxViewModel>(boxCode);
                                        boxViewModel.IsFull = CurrentItem.BoxSize == boxCode.BottleCount;
                                        //boxViewModel.BottleCount = boxCode.BottleCount;
                                        if (!BoxCodes.Any(p => p.BoxCode == boxCode.Code))
                                        {
                                            BoxCodes.Add(boxViewModel);
                                        }
                                        //return;
                                    }
                                    _soundService.PlayInfo(CodeType.PalletCode);
                                    return;
                                }
                                //未装箱 继续装箱
                                else
                                {
                                    PalletCode = palletDetail.Code;
                                    _soundService.PlayInfo(CodeType.PalletCode);
                                    return;
                                }
                            }
                            UiService.GrowlWarning("托码无效", CodeType.PalletCode);
                            return;
                        }
                        catch (ApiException ex)
                        {
                            UiService.GrowlWarning(ex.Message, CodeType.BoxCode, ex);
                        }
                        catch (Exception ex)
                        {
                            UiService.GrowlError(ex.Message, CodeType.BoxCode, ex);
                        }
                    }
                    //有商品，只能扫空托码继续装箱
                    else
                    {
                        var request = new GetPalletRequest(code, CurrentEnterpriseId);
                        try
                        {
                            var pallet = await _xkmService.GetPalletAsync(request);
                            if (pallet != null && !pallet.ItemId.HasValue)
                            {
                                PalletCode = pallet.Code;
                                _soundService.PlayInfo(CodeType.PalletCode);
                                return;
                            }
                            else
                            {
                                UiService.GrowlWarning("此托码已使用，请换个托码", CodeType.PalletCode);
                                return;
                            }
                        }
                        catch (ApiException ex)
                        {
                            UiService.GrowlWarning(ex.Message, CodeType.BoxCode, ex);
                        }
                        catch (Exception ex)
                        {
                            UiService.GrowlError(ex.Message, CodeType.BoxCode, ex);
                        }
                    }
                }
                UiService.GrowlWarning("托码已扫描，请删除后再扫", CodeType.PalletCode);
            }

        }

        public void Receive(ValueChangedMessage<List<string?>> message)
        {
            if (message != null)
            {
                RefreshBoxCodesCommand.Execute(null);
            }
        }
        #endregion
    }
}
